﻿using Bogus;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using WpfPractice.MVVM;

namespace WpfPractice.ViewModel
{
    public class TestDataGridViewModel : NotifyPropertyChanged
    {
        //【1】ObservableCollection相对于List在向集合中添加删除数据的时候会触发CollectionChanged事件
        //但是存储的元素的本身的属性发生变化事检测不到的
        //【2】BindingList相对于ObservableCollection集合中的元素本身的属性发生变化也会被检测到
        public BindingList<Employee> Employees { get; set; }
        public String Title { get; } = "DataGrid Demo";
        public TestDataGridViewModel()
        {
            this.Employees = new BindingList<Employee>(Employee.FakeMany(10).ToList());
            this.Employees.ListChanged += (object sender, ListChangedEventArgs e) =>
            {
                OnPropertyChanged(nameof(TotalSalary));
            };
        }
        public RelayCommand AddNew
        {
            get => new RelayCommand((Object e) =>
            {
                Employees.Add(Employee.FakeOne());
                //新增一条数据后，主动触发更新
                //注册了CollectionChanged事件后就不需要单独触发了
                //OnPropertyChanged(nameof(TotalSalary));
            });
        }
        public RelayCommand Promote
        {
            get => new RelayCommand((Object e) =>
            {
                foreach (Employee emp in Employees)
                {
                    emp.Salary += 1000;
                }
                //改成BindingList后元素本身的属性也能被监测到，就不需要在这里主动触发了
                //OnPropertyChanged(nameof(TotalSalary));
            });
        }
        public int TotalSalary => Employees.Sum(x => x.Salary);
    }
    public class Employee : NotifyPropertyChanged
    {
        public int Id { get; private set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        //public int Salary { get => value; set { }; }
        //只有实现了INotifyPropertyChanged，才会被BindList的ListChanged事件监测到改变
        //ObservableCollection的CollectionChanged事件只会监测集合中的元素是否增删，元素本身的属性监测不到
        private int _salary;
        public int Salary
        {
            get { return _salary; }
            set { _salary = value; OnPropertyChanged(nameof(Salary)); }
        }
        public DateTime Birthday { get; set; }
        private static readonly Faker<Employee> employeeFaker = new Faker<Employee>()
            .RuleFor(e => e.Id, f => f.IndexFaker)
            .RuleFor(e => e.FirstName, f => f.Person.FirstName)
            .RuleFor(e => e.LastName, f => f.Person.LastName)
            .RuleFor(e => e.Birthday, f => f.Person.DateOfBirth)
            .RuleFor(e => e.Salary, f => f.Random.Int(5, 60) * 1000);
        public static Employee FakeOne() => employeeFaker.Generate();
        public static IEnumerable<Employee> FakeMany(int count) => employeeFaker.Generate(count);
    }
}
